/********************************************
 * 功能说明: Project实体与DTO之间接口数据转换实现
 * 模块名称:
 * 系统名称:
 * 软件版权: Frank
 * 系统版本: 1.0.0.1
 * 开发人员:
 * 开发时间: 2019-12-18 18:41:08
 * 审核人员:
 * 相关文档:
 * 修改记录: 修改日期 修改人员 修改说明
 *********************************************/
package com.spring.arch.uaa.web.converter;

import com.spring.arch.uaa.errorcode.UaaErrorCode;
import com.spring.arch.uaa.web.dto.WebProjectDTO;
import com.spring.arch.common.converter.AbstractConverter;
import com.spring.arch.common.exception.ExceptionHolder;
import com.spring.arch.common.idgenerator.IdGenerator;
import com.spring.arch.uaa.enums.Constant;
import com.spring.arch.uaa.model.*;
import com.spring.arch.uaa.repository.*;
import com.spring.arch.uaa.web.dto.WebProjectDTO;
import lombok.NonNull;
import org.hibernate.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

import javax.persistence.EntityManager;

import static com.spring.arch.uaa.errorcode.UaaErrorCode.*;

/**
 * Project实体与DTO之间接口数据转换实现
 *
 * @author
 * @version 1.0.0.1
 * @since 2019-12-18 18:41:08
 */
@Component
public class WebProjectConverter extends AbstractConverter<Project, WebProjectDTO> {

    @Autowired
    private EntityManager entityManager;
    @Autowired
    private ProjectRepository projectRepository;
    @Autowired
    private OrganizationRepository organizationRepository;
    @Autowired
    private TenantRepository tenantRepository;
    @Autowired
    private WebTenantEmployeeConverter tenantEmployeeConverter;
    @Autowired
    private TenantEmployeeRepository tenantEmployeeRepository;
    @Autowired
    private ProjectDatasourceRepository projectDatasourceRepository;

    @Override
    public Project toModel(@NonNull final WebProjectDTO dto) {
        if(dto.isNew()) {
            return constructModel(dto);
        } else {
            return updateModel(dto);
        }
    }

    @Override
    public WebProjectDTO toDTO(@NonNull final Project model) {
        final WebProjectDTO dto = new WebProjectDTO();

        dto.setId(model.getId());
        dto.setCode(model.getCode());
        dto.setName(model.getName());
        dto.setType(model.getType());
        dto.setTypeName(model.getType().getCode());
        dto.setAreaId(model.getAreaId());
        dto.setAddress(model.getAddress());
        dto.setRemarks(model.getRemarks());
        dto.setStatus(model.getStatus());
        dto.setRootOrganizationId(model.getRootOrganization().getId());
        dto.setProjectDatasourceId(model.getDatasource().getId());
        dto.setTenantId(model.getTenant().getId());


        // 获取租户信息
        TenantEmployee employee = tenantEmployeeRepository.findByCode(Constant.projectAdminCode(model.getCode()));
        if (employee != null) {
            dto.setProjectAdminDTO(tenantEmployeeConverter.toDTO(employee));
        }
        this.convertCommonToDTO(model, dto);

        return dto;
    }

    /**
     * 构建新Model
     */
    private Project constructModel(final WebProjectDTO dto) {
        final Project model = new Project();
        //雪花算法生成code，用于唯一区分
        model.setCode("E" + IdGenerator.uniqueCode());
        //需要查询设置组织与数据源
        Organization organization = organizationRepository.findById(dto.getRootOrganizationId())
                .orElseThrow(() -> ExceptionHolder.serviceException(UaaErrorCode.E2001003001, Project.class.getSimpleName()));
        model.setRootOrganization(organization);
        Tenant tenant = tenantRepository.findById(dto.getTenantId())
                .orElseThrow(() -> ExceptionHolder.serviceException(UaaErrorCode.E2001001001, Project.class.getSimpleName()));
        model.setTenant(tenant);
        //更新时候用
        if (null != dto.getProjectDatasourceId()) {
            ProjectDatasource projectDatasource = this.projectDatasourceRepository.findById(dto.getProjectDatasourceId())
                    .orElseThrow(() -> ExceptionHolder.serviceException(UaaErrorCode.E2001007006, Project.class.getSimpleName()));
            model.setDatasource(projectDatasource);
        }
        this.dtoToModel(dto, model);
        return model;
    }

    /**
     * 更新Model
     */
    private Project updateModel(final WebProjectDTO dto) {
        final Project model = this.projectRepository.findById(dto.getId())
                .orElseThrow(() -> ExceptionHolder.serviceException(UaaErrorCode.E2001002001, Project.class.getSimpleName()));
        entityManager.unwrap(Session.class).evict(model);
        this.dtoToModel(dto, model);
        return model;
    }

    private void dtoToModel(final WebProjectDTO dto, final Project model) {
        model.setName(dto.getName());
        model.setType(dto.getType());
        model.setAreaId(dto.getAreaId());
        model.setAddress(dto.getAddress());
        model.setRemarks(dto.getRemarks());
        model.setStatus(dto.getStatus());
    }
}
